from django.contrib.auth.models import Group
from django.contrib.auth import authenticate, get_user_model
from rest_framework import serializers
from rest_framework_jwt.settings import api_settings

User = get_user_model()


class GroupSerializer(serializers.ModelSerializer):
    class Meta:
        model = Group
        fields = ('id', 'name')


class UserSerializer(serializers.ModelSerializer):
    groups = serializers.SerializerMethodField()

    class Meta:
        model = User
        fields = ('id', 'username', 'mobile', 'email', 'groups')

    def get_groups(self, user):
        return list(user.groups.values('id', 'name'))


class UserCreateSerializer(serializers.ModelSerializer):
    password = serializers.CharField(write_only=True)
    groups = serializers.ListField(child=serializers.IntegerField(), write_only=True)

    class Meta:
        model = User
        fields = ('username', 'password', 'mobile', 'email', 'groups')

    def create(self, validated_data):
        groups = validated_data.pop('groups', [])
        try:
            admin_group = Group.objects.get(name='管理员')
            is_admin = admin_group.id in groups
        except:
            is_admin = False

        if is_admin:
            user = User.objects.create_superuser(
                username=validated_data['username'],
                password=validated_data['password'],
                email=validated_data['email'],
                mobile=validated_data['mobile'],
            )
        else:
            user = User.objects.create_user(
                username=validated_data['username'],
                password=validated_data['password'],
                email=validated_data['email'],
                mobile=validated_data['mobile'],
            )
        for group_id in groups:
            group = Group.objects.get(id=group_id)
            user.groups.add(group)
        return user


class UserUpdateSerializer(serializers.ModelSerializer):
    password = serializers.CharField(write_only=True, required=False)
    groups = serializers.ListField(child=serializers.IntegerField(), write_only=True)

    class Meta:
        model = User
        fields = ('id', 'mobile', 'email', 'password', 'groups')

    def update(self, instance, validated_data):
        groups = validated_data.pop('groups', [])
        if 'password' in validated_data:
            instance.set_password(validated_data['password'])
        if 'email' in validated_data:
            instance.email = validated_data['email']
        if 'mobile' in validated_data:
            instance.mobile = validated_data['mobile']
        instance.save()
        # 添加新的group
        for group_id in groups:
            group = Group.objects.get(id=group_id)
            instance.groups.add(group)
        # 删除不在新的groups中的group
        for group in instance.groups.all():
            if group.id not in groups:
                instance.groups.remove(group)
        return instance


class UserLoginSerializer(serializers.Serializer):
    username = serializers.CharField()
    password = serializers.CharField(write_only=True)

    def validate(self, data):
        user = authenticate(username=data['username'], password=data['password'])
        if user and user.is_active:
            jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
            jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
            payload = jwt_payload_handler(user)
            token = jwt_encode_handler(payload)
            return {
                'token': token,
                'user_info': UserSerializer(user).data
            }
        else:
            raise serializers.ValidationError('Incorrect credentials')

